import {Button, Card, Collapse, Divider, Input, Space, Tag, Timeline} from "antd";
import Web3 from "web3";
import React from "react";

let web3;
const {Panel} = Collapse;
const fromAddress = '0x09914405d555ADe2608ea8551F7873A6498AC80b';   // 默认账户

function Demo1() {
    initWeb3()

    return (
        <>
            <Version/>

            <Contract1/>

            <PreBlockInfoContract/>

        </>
    )
}

function initWeb3(){
    if (typeof web3 !== "undefined") {
        web3 = new Web3(web3.currentProvider)
    } else {
        web3 = new Web3(new Web3.providers.HttpProvider("https://ropsten.infura.io/v3/fac5e84d57a34cc48649f06b14ea47fb"))
    }
}

function Version(){
    return (
        <>
            Web3 Version: <Tag color="green">{web3.version}</Tag>
            <Divider />
        </>
    )
}

function Contract1() {


    const [value, setValue] = React.useState("");
    const newValue = React.useRef(0)

    let contractABI = [
        {
            "constant": false,
            "inputs": [
                {
                    "name": "x",
                    "type": "uint256"
                }
            ],
            "name": "set",
            "outputs": [],
            "payable": false,
            "stateMutability": "nonpayable",
            "type": "function"
        },
        {
            "constant": true,
            "inputs": [],
            "name": "get",
            "outputs": [
                {
                    "name": "",
                    "type": "uint256"
                }
            ],
            "payable": false,
            "stateMutability": "view",
            "type": "function"
        }
    ]
    let contractAddress = "0xF234c791d52F2b2286677ec35a7d666d058Df1dB"
    web3.eth.defaultAccount = fromAddress;

    let contract = new web3.eth.Contract(contractABI, contractAddress)

    function QueryValue() {

        contract.methods.get().call().then(function (v, err) {
            console.log("err", err)
            console.log("v", v)
            setValue(v)
        })

    }

    function SetValue() {
        contract.methods.set(newValue.current.state.value).send({from: fromAddress}).then(function (res) {
            console.log("set res", res)
        })
    }

    return (
        <>
            <Collapse defaultActiveKey={['1']}>
                <Panel header="SimpleStorage" key="1">
                    <div>
                        当前的值：（<span>{value}</span>）
                        <Button type="primary" onClick={QueryValue}>查看值</Button>
                    </div>
                    <div>
                        <Space direction="vertical">
                            <Input placeholder="Basic usage" ref={newValue}/>
                        </Space>
                        <Button type="primary" onClick={SetValue}>设置为</Button>
                    </div>
                </Panel>
            </Collapse>
        </>
    )
}

// 预定义变量
function PreBlockInfoContract(){

    let contractABI =[
        {
            "inputs": [],
            "name": "BlockInfo",
            "outputs": [
                {
                    "internalType": "address",
                    "name": "coinbase",
                    "type": "address"
                },
                {
                    "internalType": "uint256",
                    "name": "number",
                    "type": "uint256"
                },
                {
                    "internalType": "uint256",
                    "name": "gasLimit",
                    "type": "uint256"
                },
                {
                    "internalType": "uint256",
                    "name": "timestamp",
                    "type": "uint256"
                },
                {
                    "internalType": "uint256",
                    "name": "diff",
                    "type": "uint256"
                }
            ],
            "stateMutability": "view",
            "type": "function"
        },
        {
            "inputs": [],
            "name": "MsgInfo",
            "outputs": [
                {
                    "internalType": "bytes",
                    "name": "data",
                    "type": "bytes"
                },
                {
                    "internalType": "uint256",
                    "name": "gas",
                    "type": "uint256"
                },
                {
                    "internalType": "address",
                    "name": "sender",
                    "type": "address"
                },
                {
                    "internalType": "bytes4",
                    "name": "sig",
                    "type": "bytes4"
                }
            ],
            "stateMutability": "view",
            "type": "function"
        }
    ];
    let contractAddress = "0xb445f0D59aF24f56062494cF26b67dD600DB61fC"
    let contract = new web3.eth.Contract(contractABI, contractAddress)

    const [blockInfo,setBlockInfo] = React.useState({});
    const [msgInfo,setMsgInfo] = React.useState({});

    function GetBlockInfo(){
        contract.methods.BlockInfo().call().then(function (v) {
            console.log("BlockInfo", v)
            setBlockInfo(v)
        })
    }

    function GetMsgInfo(){
        contract.methods.MsgInfo().call().then(function (v) {
            console.log("MsgInfo", v)
            setMsgInfo(v)
        })
    }

    return (
        <>
            <Card title="合约 - 预定义变量的信息" >
                <Timeline>
                    <Timeline.Item>挖出当前区块的矿工地址：{blockInfo.coinbase}</Timeline.Item>
                    <Timeline.Item>当前区块难度：{blockInfo.diff}</Timeline.Item>
                    <Timeline.Item>当前区块gas限额：{blockInfo.gasLimit}</Timeline.Item>
                    <Timeline.Item>当前区块号：{blockInfo.number}</Timeline.Item>
                    <Timeline.Item>当前区块以秒计的时间戳：{blockInfo.timestamp}</Timeline.Item>
                    <Timeline.Item>完整的calldata：{msgInfo.data}</Timeline.Item>
                    <Timeline.Item>剩余gas：{msgInfo.gas}</Timeline.Item>
                    <Timeline.Item>当前调用的消息发送者：{msgInfo.sender}</Timeline.Item>
                    <Timeline.Item>calldata的前4个字节（也就是函数标识符）：{msgInfo.sig}</Timeline.Item>
                </Timeline>
                <div>
                    <Button type="primary" onClick={GetBlockInfo}>点击查询当前区块的信息</Button>
                    &nbsp;
                    <Button type="primary" onClick={GetMsgInfo}>点击查询本次调用的信息</Button>
                </div>
            </Card>
        </>
    )
}

export default Demo1